class MyTable {
    /**
     * @param {HTMLDivElement} tableEl - 表格元素，需要DIV元素
     * @param {{maxHeight: number, refresh: () => void | Promise<void>, load: () => void | Promise<void>}} opts - 选项
     */
    constructor(tableEl, opts) {
        if (tableEl.dataset.inited) {
            throw new Error('The table has already been initialized.')
        }
        tableEl.dataset.inited = 1
        this.tableEl = tableEl
        this.opts = opts

        this.maxHeight = opts.maxHeight
        tableEl.style.maxHeight = opts.maxHeight + 'px'

        this.tipsHeight = 30
        this.checkableDistance = 30

        this.hasMore = true

        this.refreshing = false
        this.loading = false
        this.willRefresh = false

        this.touching = false
        this.touchstartY = 0

        this.refreshFlagEl = tableEl.querySelector('.refresh-flag')
        this.refreshFlagTipsEl = this.refreshFlagEl.querySelector('.tips')
        this.loadFlagEl = tableEl.querySelector('.load-flag')
        this.loadFlagTipsEl = this.loadFlagEl.querySelector('.tips')

        this.refreshFlagTipsEl.style.width = tableEl.clientWidth + 'px'
        this.loadFlagTipsEl.style.width = tableEl.clientWidth + 'px'

        tableEl.addEventListener('scroll', this.onScroll.bind(this))
        tableEl.addEventListener('touchstart', this.onTouchStart.bind(this))
        tableEl.addEventListener('touchmove', this.onTouchMove.bind(this))
        tableEl.addEventListener('touchend', this.onTouchEnd.bind(this))
    }
    get fetching() {
        return this.refreshing || this.loading
    }
    checkAndSetStyle() {
        const scrollDistanceTop = this.tableEl.scrollTop
        if (scrollDistanceTop > this.checkableDistance) {
            this.tableEl.classList.add('un-top')
        } else {
            this.tableEl.classList.remove('un-top')
        }

        const scrollDistanceRight = this.tableEl.scrollWidth - this.tableEl.clientWidth - this.tableEl.scrollLeft
        if (scrollDistanceRight > this.checkableDistance) {
            this.tableEl.classList.add('un-right')
        } else {
            this.tableEl.classList.remove('un-right')
        }

        const scrollDistanceLeft = this.tableEl.scrollLeft
        if (scrollDistanceLeft > this.checkableDistance) {
            this.tableEl.classList.add('un-left')
        } else {
            this.tableEl.classList.remove('un-left')
        }

        this.refreshFlagTipsEl.style.transform = `translateX(${scrollDistanceLeft}px)`
        this.loadFlagTipsEl.style.transform = `translateX(${scrollDistanceLeft}px)`
    }
    onScroll() {
        this.checkAndSetStyle()
        if (!this.fetching && this.hasMore) {
            const scrollDistanceBottom = this.tableEl.scrollHeight - this.tableEl.clientHeight - this.tableEl.scrollTop
            document.getElementById('remark').innerText = 'scrollDistanceBottom:' + scrollDistanceBottom
            const isSrollToBottom = scrollDistanceBottom <= 0
            if (isSrollToBottom) {
                this.opts.load()
            }
        }
    }
    onTouchStart(e) {
        this.touching = true
        this.touchstartY = e.touches[0].clientY
    }
    onTouchMove(e) {
        if (!this.touching && this.fetching) {
            return
        }

        this.willRefresh = false

        const deltaY = e.touches[0].clientY - this.touchstartY

        if (this.tableEl.scrollTop === 0) {
            if (deltaY >= this.tipsHeight) {
                this.refreshFlagTipsEl.style.height = this.tipsHeight + 'px'
                this.refreshFlagTipsEl.innerText = '松开手指开始刷新'
                this.willRefresh = true
            } else if (deltaY > 0) {
                this.refreshFlagTipsEl.style.height = deltaY + 'px'
                this.refreshFlagTipsEl.innerText = '继续下拉触发刷新'
            } else {
                this.refreshFlagTipsEl.style.height = '0'
            }
        }
    }
    onTouchEnd() {
        this.touching = false
        if (this.fetching) {
            return
        }
        if (this.willRefresh) {
            this.opts.refresh()
        } else {
            this.refreshFlagTipsEl.style.height = '0'
        }
    }
    /**
     * 设置刷新状态
     * @param {boolean} value
     */
    setRefreshing(value) {
        this.refreshing = value
        if (this.refreshing) {
            this.refreshFlagTipsEl.innerText = '刷新中...'
        } else {
            this.refreshFlagTipsEl.style.height = '0'
        }
    }
    /**
     * 设置加载状态
     * @param {boolean} value
     */
    setLoading(value) {
        this.loading = value
        this.calcLoadStatus()
    }
    /**
     * 设置是否有更多数据
     * @param {boolean} value
     */
    setHasMore(value) {
        this.hasMore = value
        this.calcLoadStatus()
    }
    calcLoadStatus() {
        if (this.loading) {
            this.loadFlagTipsEl.innerText = '加载中...'
        } else {
            if (this.hasMore) {
                this.loadFlagTipsEl.innerText = '继续上拉触发加载'
            } else {
                this.loadFlagTipsEl.innerText = '没有更多数据了'
            }
        }
    }
}
